package info.batcloud.fanli.core.service.impl;

import com.ctospace.archit.common.pagination.Paging;
import info.batcloud.fanli.core.dto.ServiceItemDTO;
import info.batcloud.fanli.core.entity.ServiceItem;
import info.batcloud.fanli.core.enums.ServiceItemStatus;
import info.batcloud.fanli.core.helper.PagingHelper;
import info.batcloud.fanli.core.repository.ServiceItemRepository;
import info.batcloud.fanli.core.service.ServiceItemService;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.inject.Inject;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import java.util.Date;
import java.util.List;

@Service
public class ServiceItemServiceImpl implements ServiceItemService {

    @Inject
    private ServiceItemRepository serviceItemRepository;

    @Override
    public Paging<ServiceItemDTO> search(SearchParam param) {
        Specification<ServiceItem> specification = (root, query, cb) -> {
            Predicate predicate = cb.conjunction();
            List<Expression<Boolean>> expressions = predicate.getExpressions();
            if (param.getStatus() != null) {
                expressions.add(cb.equal(root.get("status"), param.getStatus()));
            } else {
                expressions.add(cb.notEqual(root.get("status"), ServiceItemStatus.DELETED));
            }
            if (param.getService() != null) {
                expressions.add(cb.equal(root.get("service"), param.getService()));
            }
            return predicate;
        };
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        Pageable pageable = new PageRequest(param.getPage() - 1,
                param.getPageSize(), sort);
        Page<ServiceItem> page = serviceItemRepository.findAll(specification, pageable);
        return PagingHelper.of(page, item -> toBO(item), param.getPage(), param.getPageSize());
    }

    @Override
    public void saveServiceItem(ServiceItemSaveParam param) {
        ServiceItem si = new ServiceItem();
        si.setCreateTime(new Date());
        si.setPrice(param.getPrice());
        si.setService(param.getService());
        si.setStatus(param.getStatus());
        si.setTimeUnit(param.getTimeUnit());
        this.serviceItemRepository.save(si);
    }

    @Override
    public void setStatus(long id, ServiceItemStatus status) {
        ServiceItem si = serviceItemRepository.findOne(id);
        si.setStatus(status);
        serviceItemRepository.save(si);
    }

    @Override
    public void updateServiceItem(long id, ServiceItemUpdateParam param) {
        ServiceItem si = serviceItemRepository.findOne(id);
        si.setUpdateTime(new Date());
        si.setPrice(param.getPrice());
        si.setService(param.getService());
        si.setStatus(param.getStatus());
        si.setTimeUnit(param.getTimeUnit());
        this.serviceItemRepository.save(si);
    }

    private ServiceItemDTO toBO(ServiceItem si) {
        ServiceItemDTO bo = new ServiceItemDTO();
        BeanUtils.copyProperties(si, bo);
        return bo;
    }
}
